package com.excilys.formation.project.entities;

import java.io.Serializable;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import org.hibernate.annotations.Index;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;

/**
 * Client est la classe de lien avec la table client en base pour l'ORM.
 * 
 * @author excilys
 */
@Entity
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "login" }) })
@SuppressWarnings("serial")
public class Client implements Serializable {
	/**
	 * Clef primaire du client.
	 */
	private long id;
	/**
	 * Nom du client.
	 */
	private String nom;
	/**
	 * Prénom du client.
	 */
	private String prenom;
	/**
	 * Identifiant (unique) du client pour se connecter sur le site.
	 */
	private String login;
	/**
	 * Mot de passe du client pour se connecter sur le site. Doit être encrypté en SHA-256.
	 */
	private String password;

	/**
	 * Comptes possédés par le client.
	 */
	private Set<Compte> comptes;

	/**
	 * Taille minimale de l'identifiant de connection.
	 */
	public static final int LOGIN_MIN_SIZE = 6;
	/**
	 * Taille maximale de l'identifiant de connection.
	 */
	public static final int LOGIN_MAX_SIZE = 20;
	/**
	 * Taille du mot de passe de connection (SHA-256).
	 */
	private static final int PASSWORD_SIZE = 64;

	/**
	 * Renvoie la clef primaire Change la clef primaire (auto générée).
	 * 
	 * @return id
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	public long getId() {
		return id;
	}

	/**
	 * Change la clef primaire (auto générée).
	 * 
	 * @param id
	 *            Clef primaire du client.
	 */
	public void setId(final long id) {
		this.id = id;
	}

	/**
	 * Renvoie le nom du client.
	 * 
	 * @return nom
	 */
	@NotEmpty
	@Index(name = "Nom")
	public String getNom() {
		return nom;
	}

	/**
	 * Change le nom du client.
	 * 
	 * @param nom
	 *            Nom du client.
	 */
	public void setNom(final String nom) {
		this.nom = nom;
	}

	/**
	 * Renvoie le prénom du client.
	 * 
	 * @return prenom
	 */
	@NotEmpty
	@Index(name = "Prenom")
	public String getPrenom() {
		return prenom;
	}

	/**
	 * Change le prénom du client.
	 * 
	 * @param prenom
	 *            Prénom du client.
	 */
	public void setPrenom(final String prenom) {
		this.prenom = prenom;
	}

	/**
	 * Renvoie l'identifiant de connection du client (entre 6 et 20 charactères). Unique
	 * 
	 * @return login
	 */
	@NotEmpty
	@Length(min = LOGIN_MIN_SIZE, max = LOGIN_MAX_SIZE)
	public String getLogin() {
		return login;
	}

	/**
	 * Change l'identifiant de connection du client (entre 6 et 20 charactères).
	 * 
	 * @param login
	 *            Identifiant du client pour se connecter sur le site.
	 */
	public void setLogin(final String login) {
		this.login = login;
	}

	/**
	 * Renvoie le mot de passe de connection du client (minimum 6 charactères).
	 * 
	 * @return password
	 */
	@NotEmpty
	@Length(min = PASSWORD_SIZE, max = PASSWORD_SIZE)
	public String getPassword() {
		return password;
	}

	/**
	 * Change le mot de passe de connection du client (minimum 6 charactères).
	 * 
	 * @param password
	 *            Mot de passe du client pour se connecter sur le site.
	 */
	public void setPassword(final String password) {
		this.password = password;
	}

	/**
	 * Renvoie l'ensemble des comptes possédés par le client.
	 * 
	 * @return comptes
	 */
	@OneToMany(mappedBy = "client", fetch = FetchType.LAZY)
	public Set<Compte> getComptes() {

		return comptes;
	}

	/**
	 * Change l'ensemble des comptes possédés par le client.
	 * 
	 * @param comptes
	 *            Le nouvel ensemble de comptes.
	 */
	public void setComptes(final Set<Compte> comptes) {
		this.comptes = comptes;
	}

}
